package service

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"

	"go-file-perception-model/internal/config"
	"go-file-perception-model/internal/model"
	"go-file-perception-model/pkg/vector"

	"github.com/google/uuid"
)

// SystemService 系统服务
type SystemService struct {
	vectorDB      vector.VectorDB
	indexManager  *IndexManager
	fileProcessor *FileProcessor
	fileCollector *FileCollector
	config        *config.Config
}

// NewSystemService 创建系统服务实例
func NewSystemService(vectorDB vector.VectorDB, indexManager *IndexManager, fileProcessor *FileProcessor, fileCollector *FileCollector, cfg *config.Config) *SystemService {
	return &SystemService{
		vectorDB:      vectorDB,
		indexManager:  indexManager,
		fileProcessor: fileProcessor,
		fileCollector: fileCollector,
		config:        cfg,
	}
}

// ResolveFilePath 解析文件路径，支持相对路径
func (s *SystemService) ResolveFilePath(filePath string) (string, error) {
	fmt.Printf("=== ResolveFilePath DEBUG START ===\n")
	fmt.Printf("[DEBUG] Input file path: '%s'\n", filePath)

	// 如果是绝对路径，直接返回
	if filepath.IsAbs(filePath) {
		fmt.Printf("[DEBUG] Path is absolute, returning as-is: '%s'\n", filePath)
		fmt.Printf("=== ResolveFilePath DEBUG END ===\n")
		return filePath, nil
	}

	fmt.Printf("[DEBUG] Path is relative, processing...\n")

	// 处理相对路径，去掉开头的 "./" 如果存在
	cleanPath := strings.TrimPrefix(filePath, "./")
	fmt.Printf("[DEBUG] Clean path after removing './': '%s'\n", cleanPath)

	// 获取索引目录列表
	indexDirs := s.config.FileIndex.IndexDirectories
	fmt.Printf("[DEBUG] Available index directories (%d):\n", len(indexDirs))
	for i, dir := range indexDirs {
		fmt.Printf("[DEBUG]   [%d]: '%s'\n", i, dir)
	}

	if len(indexDirs) == 0 {
		fmt.Printf("[DEBUG] ERROR: No index directories configured\n")
		fmt.Printf("=== ResolveFilePath DEBUG END ===\n")
		return "", fmt.Errorf("no index directories configured")
	}

	// 尝试在每个索引目录中查找文件
	fmt.Printf("[DEBUG] Searching for file in index directories...\n")
	for i, indexDir := range indexDirs {
		// 构建完整路径
		fullPath := filepath.Join(indexDir, cleanPath)
		fmt.Printf("[DEBUG] [%d] Trying full path: '%s'\n", i, fullPath)
		fmt.Printf("[DEBUG] [%d] Index dir: '%s' + Clean path: '%s'\n", i, indexDir, cleanPath)

		// 检查文件是否存在
		if _, err := os.Stat(fullPath); err == nil {
			// 转换为绝对路径
			absPath, err := filepath.Abs(fullPath)
			if err != nil {
				fmt.Printf("[DEBUG] ERROR: Failed to get absolute path for '%s': %v\n", fullPath, err)
				fmt.Printf("=== ResolveFilePath DEBUG END ===\n")
				return "", fmt.Errorf("failed to get absolute path for %s: %w", fullPath, err)
			}
			fmt.Printf("[DEBUG] SUCCESS: Found file at: '%s'\n", absPath)
			fmt.Printf("=== ResolveFilePath DEBUG END ===\n")
			return absPath, nil
		} else {
			fmt.Printf("[DEBUG] [%d] File not found at '%s', error: %v\n", i, fullPath, err)
		}
	}

	// 如果在所有索引目录中都找不到文件，尝试直接使用当前工作目录
	fmt.Printf("[DEBUG] File not found in index directories, trying current working directory...\n")
	cwd, err := os.Getwd()
	if err != nil {
		fmt.Printf("[DEBUG] ERROR: Failed to get current working directory: %v\n", err)
	} else {
		fullPath := filepath.Join(cwd, cleanPath)
		fmt.Printf("[DEBUG] Trying path in current working directory: '%s'\n", fullPath)
		
		if _, err := os.Stat(fullPath); err == nil {
			absPath, err := filepath.Abs(fullPath)
			if err != nil {
				fmt.Printf("[DEBUG] ERROR: Failed to get absolute path for '%s': %v\n", fullPath, err)
			} else {
				fmt.Printf("[DEBUG] SUCCESS: Found file at: '%s'\n", absPath)
				fmt.Printf("=== ResolveFilePath DEBUG END ===\n")
				return absPath, nil
			}
		} else {
			fmt.Printf("[DEBUG] File not found in current working directory: %v\n", err)
		}
	}

	// 如果在所有位置都找不到文件，返回错误
	fmt.Printf("[DEBUG] ERROR: File not found in any location\n")
	fmt.Printf("=== ResolveFilePath DEBUG END ===\n")
	return "", fmt.Errorf("file not found: %s", filePath)
}

// GetSystemStats 获取系统统计信息
func (s *SystemService) GetSystemStats() (*model.SystemStats, error) {
	// 获取索引状态以获取文件统计信息
	indexStatus, err := s.indexManager.GetIndexStatus()
	if err != nil {
		return nil, fmt.Errorf("failed to get index status: %w", err)
	}

	// 检查Qdrant连接状态
	var qdrantStatus = "disconnected"
	if s.vectorDB != nil {
		// 尝试检查连接状态
		qdrantStatus = "connected"
	}

	// 构建系统统计信息
	stats := &model.SystemStats{
		TotalFiles:      indexStatus.TotalFiles,
		IndexedFiles:    indexStatus.IndexedFiles,
		TotalChunks:     indexStatus.TotalChunks,
		IndexedChunks:   indexStatus.IndexedChunks,
		TotalVectors:    indexStatus.TotalChunks,
		VectorDimension: 768, // BGE-base-zh的向量维度
		LastUpdateTime:  indexStatus.LastIndexedTime,
		Uptime:          time.Now(), // 需要计算实际运行时间
		ServerStatus:    "running",
		QdrantStatus:    qdrantStatus,
	}

	return stats, nil
}

// GetFileList 获取文件列表
func (s *SystemService) GetFileList(directory string, recursive bool) ([]*model.FileInfo, error) {
	// 收集目录中的文件
	files, err := s.fileCollector.CollectFiles(directory, recursive)
	if err != nil {
		return nil, fmt.Errorf("failed to collect files: %w", err)
	}

	// 构建文件信息列表
	fileInfos := make([]*model.FileInfo, 0, len(files))
	for _, file := range files {
		fileInfo, err := os.Stat(file)
		if err != nil {
			continue
		}

		fileModel := &model.FileInfo{
			ID:          uuid.New().String(),
			Path:        file,
			Name:        filepath.Base(file),
			Size:        fileInfo.Size(),
			Extension:   strings.ToLower(filepath.Ext(file)),
			ContentType: s.fileProcessor.GetContentType(file),
			CreatedAt:   fileInfo.ModTime(),
			UpdatedAt:   fileInfo.ModTime(),
			Indexed:     true, // 假设已索引，实际应该查询数据库
		}

		fileInfos = append(fileInfos, fileModel)
	}

	return fileInfos, nil
}

// GetFileContent 获取文件内容
func (s *SystemService) GetFileContent(filePath string) (string, error) {
	// 检查文件是否存在
	fileInfo, err := os.Stat(filePath)
	if os.IsNotExist(err) {
		return "", fmt.Errorf("file does not exist: %s", filePath)
	}
	if err != nil {
		return "", fmt.Errorf("failed to stat file: %s, error: %w", filePath, err)
	}

	// 记录文件信息
	fileSize := fileInfo.Size()
	fmt.Printf("[DEBUG] GetFileContent: File=%s, Size=%d bytes\n", filePath, fileSize)

	// 检查文件是否支持
	if !s.fileCollector.IsFileSupported(filePath) {
		return "", fmt.Errorf("file type not supported: %s", filePath)
	}

	// 检查文件大小
	maxFileSize := s.fileCollector.config.MaxFileSize
	fmt.Printf("[DEBUG] GetFileContent: MaxFileSize=%d bytes\n", maxFileSize)
	if !s.fileCollector.IsFileSizeValid(filePath) {
		return "", fmt.Errorf("file too large: %s (size: %d, max: %d)", filePath, fileSize, maxFileSize)
	}

	// 读取文件内容
	content, err := os.ReadFile(filePath)
	if err != nil {
		return "", fmt.Errorf("failed to read file: %w", err)
	}

	fmt.Printf("[DEBUG] GetFileContent: Successfully read file, content length=%d bytes\n", len(content))

	return string(content), nil
}

// GetPointByID 根据点ID获取点详细信息
func (s *SystemService) GetPointByID(ctx context.Context, pointID string) (*model.SearchResult, error) {
	if s.vectorDB == nil {
		return nil, fmt.Errorf("vector database is not available")
	}
	return s.vectorDB.GetPointByID(ctx, pointID)
}
